<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <title>Smoke Test</title>
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1"
    />
    <link rel="stylesheet" href="../style.css" />
    <link rel="icon" href="data:," />
    <style>
      math-field {
        border: 1px solid var(--editable-border);
        padding: 5px;
        margin: 10px 0 10px 0;
        border-radius: 5px;
        background: var(--editable);
        color: var(--on-editable);
        max-width: 640px;
        width: 100%;
      }
      /* math-field {
        --selection-background-color: red;
        --selection-color: #f80;
      } */
    </style>
  </head>
  <body theme="light">
    <header>
      <h1>Smoke Test</h1>
      <ul>
        <li class="current"><a href="../smoke/">Smoke</a></li>
        <li>
          <a href="../virtual-keyboard/">Virtual Keyboard</a>
        </li>
        <li>
          <a href="../mathfield-states/">States</a>
        </li>
        <li>
          <a href="../prompts/">Prompts</a>
        </li>
      </ul>
    </header>
    <main>
      <math-field id="mf"
        >1+\colorbox{blue}{$2$}+3+\colorbox{red}{4}+\colorbox{green}{\ensuremath{4}}+\text{5+\colorbox{purple}{6}}</math-field
      >
      <!-- <math-field id="mf">1+\colorbox{blue}{\ensuremath{2}}+1+2</math-field> -->

      <!-- <math-field id="mf"
        >+\raisebox{2ex}{$+x$}\raisebox{0pt}{+x}\boxed{+}</math-field
      > -->
      <!-- <math-field id="mf">=\overset{\left[\frac{0}{0}\right]}{=}=</math-field> -->

      <!-- <math-field id="mf">
        \Huge\textcolor{red}{\mathbb{Cc\frac{1}{C}}} \mbox{hello \small world}
        \textcolor{purple}{a\not=b\ne c\emph{mw}q{\em wm}q}\normalsize
        \textcolor{green}{\mathbb{Cc\frac{1}{C}}}</math-field
      > -->
      <!-- <math-field id="mf"
        >a\not=b=\left(\sqrt{\frac{1}{2+x}}\right) \left(1+\sqrt{x}\right)
        (\sqrt{\frac{1}{2+x}}) \int^\infty x</math-field
      > -->
      <!-- <math-field id="mf"
        >{\mathrlap{\raisebox{-.1em}{$-$}}\raisebox{.1em}{$\tripledash$}}\ce{A\bond{~-}B\bond{~=}C\bond{-~-}D}</math-field
      > -->
      <!-- <math-field id="mf"> \not=\not{}=\not{\in} </math-field> -->
      <!-- <math-field id="mf">\ce{A\bond{--}B\bond{=}C\bond{-~-}D}</math-field> -->
      <!-- <math-field id="mf"
        >+\kern11pt+\kern11pt plus2ex minus3pt+\mkern11mu+\mkern11mu plus1mu
        minus2mu+\mkern\thinmuskip+\mskip5mu+\mskip\thinmuskip+\hskip12pt+\mspace{12mu}+\mspace{12mu
        plus1mu minus1mu}+</math-field
      > -->

      <!-- <math-field id="mf">x^{}y^</math-field> -->
      <!-- <math-field id="mf"
        >\frac{}{1+x}\sqrt{}x^{}+y_{}+{}+\mathbb{}+\textcolor{red}{}</math-field
      > -->

      <!-- <math-field id="mf"
        >\sum^q_{n=0}\begin{pmatrix}a & b \\ c & d\\\end{pmatrix}</math-field
      > -->

      <h2>Selection</h2>
      <div class="output" id="selection"></div>

      <h2 style="margin-top: 1em">LaTeX</h2>
      <div class="output" id="latex"></div>

      <h2>MathJSON</h2>
      <div class="output" style="white-space: nowrap">
        <div id="math-json"></div>
        <div id="result"></div>
        <div id="result-latex"></div>
      </div>

      <h2>MathASCII</h2>
      <div class="output" id="mathascii"></div>

      <h2>MathML</h2>
      <div class="output" id="mathml"></div>

      <h2>Latex to Speakable Text</h2>
      <div class="output" id="latex2speech"></div>

      <div class="button-bar">
        <button id="grow">Grow</button>
        <button id="shrink">Shrink</button>
      </div>
    </main>

    <script type="module">
      import {
        renderMathInDocument,
        renderMathInElement,
        MathfieldElement,
        convertLatexToMarkup,
        convertLatexToSpeakableText,
      } from '/dist/mathlive.mjs';

      import {
        ComputeEngine,
        version,
      } from 'https://unpkg.com/@cortex-js/compute-engine?module';

      renderMathInDocument();

      const mfe = new MathfieldElement();
      document.body.appendChild(mfe);
      mfe.remove();

      // iframe.contentDocument.body.appendChild(mf.cloneNode(true));

      mathVirtualKeyboard.layouts = makeVirtualKeyboard(['x', 'y']);

      const ce = new ComputeEngine({
        latexDictionary: [
          ...ComputeEngine.getLatexDictionary(),
          {
            trigger: ['\\smallfrac'],
            parse: (parser) => {
              return [
                'Smallfrac',
                parser.matchRequiredLatexArgument() ?? ['Error', "'missing'"],
                parser.matchRequiredLatexArgument() ?? ['Error', "'missing'"],
              ];
            },
          },
        ],
      });
      ce.defineFunction('Smallfrac', {
        signature: {
          domain: 'NumericFunction',
          evaluate: (ce, args) => ce.box(args[0].N() / args[1].N()),
        },
      });

      MathfieldElement.computeEngine = ce;

      const mf = document.getElementById('mf');

      mf.onInlineShortcut = (_mf, s) => {
        if (/^[a-zA-Z][a-zA-Z0-9]*'?(_[a-zA-Z0-9]+'?)?$/.test(s)) {
          const m = s.match(/^([a-zA-Z]+)([0-9]+)$/);
          if (m) {
            if (['alpha', 'beta', 'gamma'].includes(m[1]))
              return `\\${m[1]}_{${m[2]}}`;
            return `\\mathrm{${m[1]}}_{${m[2]}}`;
          }
          return '\\mathrm{' + s + '}';
        }
        return '';
      };
      mf.macros = {
        ...mf.macros,
        // Alpha: undefined,
        minutes: '\\prime',
        smolfrac: {
          args: 2,
          def: '{}^{#1}\\!\\!/\\!{}_{#2}',
          captureSelection: true,
        },
      };

      mf.addEventListener('input', (ev) => {
        console.log('input event');
        updateContent(mf);
      });

      // mf.addEventListener('beforeinput', (ev) => {
      //   if (ev.inputType === 'insertLineBreak') console.log('enter');
      // });

      // mf.addEventListener('keydown', (ev) => {
      //   console.log('keydown', ev);
      // });

      mf.addEventListener('selection-change', (ev) => {
        const selection = mf.selection;
        document.getElementById('selection').innerHTML =
          `${label('value     ')}"${escapeHtml(
            mf.getValue(selection, 'latex')
          )}"<br>` +
          label('start     ') +
          selection.ranges[0][0] +
          '<br>' +
          label('end       ') +
          selection.ranges[0][1] +
          '<br>' +
          label('position  ') +
          mf.position +
          '<br>' +
          label('direction ') +
          '"' +
          selection.direction +
          '"<br>' +
          label('depth     ') +
          mf.getOffsetDepth(mf.position);
      });

      document.getElementById('grow').addEventListener('click', () => {
        for (let i = 0; i < 1000; i++) {
          document.body.appendChild(new MathfieldElement());
        }
      });

      document.getElementById('shrink').addEventListener('click', () => {
        document.querySelectorAll('math-field').forEach((x) => x.remove());
      });

      //
      // Handler called when the mathfield content has changed
      //
      function updateContent(mf) {
        const latex = mf.getValue('latex-expanded');
        try {
          setHtml('latex', mf.getValue('latex-expanded'));
          setHtml('math-json', mf.getValue('math-json'));
          setHtml('mathascii', mf.getValue('ascii-math'));
          setHtml('mathml', mf.getValue('math-ml'));
          // setHtml('math-json', ce.parse(mf.value));
          setHtml('latex2speech', convertLatexToSpeakableText(mf.getValue()));
          const result = mf.expression?.evaluate().latex ?? '';
          document.getElementById('result').innerText = result;
          document.getElementById('result-latex').innerText = `$$${result}$$`;

          // renderMathInElement('result-latex');
        } catch (e) {
          console.error('Error converting', e.toString());
        }
      }

      function setHtml(id, text) {
        document.getElementById(id).innerHTML = escapeHtml(text);
      }

      function label(s) {
        return `<span class='label'>${s}</span>`;
      }

      function escapeHtml(string) {
        return String(string).replace(
          /[&<>"'`= /\u200b]/g,
          (s) =>
            ({
              '&': '&amp;',
              '<': '&lt;',
              '>': '&gt;',
              '"': '&quot;',
              "'": '&#39;',
              '/': '&#x2F;',
              '`': '&#x60;',
              '=': '&#x3D;',
              '\u200b': '&amp;#zws;',
            }[s] ?? s)
        );
      }

      // First time update
      updateContent(mf);
      // renderMathInDocument();

      function makeVirtualKeyboard(variables) {
        const extraSpecificity = `.ML__keyboard .minimalist-backdrop`;
        // const customKeys = symbolsToKeycaps(variables);

        return {
          label: '',
          layers: [
            {
              style: `
                .ML__keyboard {
                  --keyboard-zindex: 2000;

                }
                .minimalist-backdrop {
                  display: flex;
                  justify-content: center;
                }
                ${extraSpecificity} .minimalist-container {
                  --keycap-height: 45px;
                  --keycap-max-width: 53px;
                  --keycap-font-size: 20px;
                  --keycap-small-font-size: 12px;
                  --keyboard-background: #f2f2f2;
                  --keycap-background-hover: #ffffff;

                  --keycap-secondary-background: #e5e5e5;
                  --keycap-secondary-background-hover: #c4c4c4;

                  --placeholder-opacity: 1;

                  padding: 15px;

                  background: var(--keyboard-background);
                  border-top-left-radius: 8px;
                  border-top-right-radius: 8px;
                  border: none;
                  box-shadow: 0px 0px 40px 0px #00000033;
                }

                @container (max-width: 744px) {
                  ${extraSpecificity} .minimalist-container {
                    padding: 4px;
                  }

                  ${extraSpecificity} .MLK__rows {
                    --keycap-gap: 5px;
                    --keycap-height: 45px;
                  }
                }

                ${extraSpecificity} .minimalist-container .action {
                  box-shadow: 0px 1px 0px #b5b5b5;
                  color: var(--keyboard-text);
                  border: none;
                }

                ${extraSpecificity} .minimalist-container .action.is-pressed {
                  transform-origin: bottom center;
                  transform: scale(1.4, 1.4);
                  background-color: var(--keycap-secondary-background-hover);
                  color: var(--keyboard-text);
                }

                ${extraSpecificity} .minimalist-container .action.is-active {
                  background-color: var(--keycap-secondary-background-hover);
                  color: var(--keyboard-text);
                }

                ${extraSpecificity} .minimalist-container .MLK__keycap:not(.ghost) {
                  box-shadow: 0px 1px 0px #b5b5b5;
                  color: var(--keyboard-text);
                  border: none;
                }

                ${extraSpecificity} .minimalist-container .MLK__keycap.is-pressed {
                  transform-origin: bottom center;
                  transform: scale(1.4, 1.4);
                  background-color: var(--keycap-background-hover);
                  color: var(--keyboard-text);
                }

                ${extraSpecificity} .minimalist-container .MLK__keycap.is-active {
                  background-color: var(--keycap-background-hover);
                  color: var(--keyboard-text);
                }

                ${extraSpecificity} .MLK__rows {
                  overflow-x: unset;
                }

                ${extraSpecificity} .MLK__rows .row {
                  justify-content: flex-start;
                }

                ${extraSpecificity} .if-can-undo, ${extraSpecificity} .if-can-redo {
                  opacity: 0.4;
                }

                .ML__keyboard.can-undo .if-can-undo, .ML__keyboard.can-redo .if-can-redo {
                  opacity: 1;
                }
              `,
              backdrop: 'minimalist-backdrop',
              container: 'minimalist-container',
              rows: [
                // customKeys,
                // customKeys.length > 0 ? ['[hr]'] : [],
                [
                  '+',
                  '-',
                  '\\times',
                  {
                    insert: '\\frac{#@}{#0}',
                    latex: '\\frac{#?}{#?}',
                    class: 'small',
                  },
                  '=',
                  '[.]',
                  '(',
                  ')',
                  { latex: '\\sqrt{#0}', class: 'small' },
                  { insert: '#@^{#?}', class: 'small', latex: '#?^{#?}' },
                ],
                ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
                ['[hr]'],
                [
                  { label: '[undo]' },
                  '[redo]',
                  '[separator]',
                  '[separator]',
                  '[separator]',
                  { label: '[separator]', width: 1.5 },
                  '[left]',
                  '[right]',
                  { label: '[backspace]', class: 'action hide-shift' },
                ],
              ],
            },
          ],
        };
      }
    </script>
  </body>
</html>
